iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0
自我挑戰組

React 個人讀書會系列 第 26

Day 26 - 共享資料狀態:Context API

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20231011/20103817GzByMEJwKj.jpg

為什麼需要 Context API?

讓我們看一個例子,DComponentFComponent 需要最頂層 AComponent 的狀態 name,此時需要將狀態 name 一層一層地往下傳遞,我們稱之為 Prop Drilling,這樣做會有一個明顯的問題,多個層級傳遞屬性會導致程式碼變得複雜且難以閱讀。

function AComponent() {
  const [name, setName] = useState("John");

  return <BComponent name={name} />
}

// 沒有使用到 name 屬性,單純傳遞下去
function BComponent({ name }) {
  return <CComponent name={name} />
}

// 沒有使用到 name 屬性,單純傳遞下去
function CComponent({ name }) {
  return <DComponent name={name} />
}

// 有使用到 name 屬性
// 子元件 FComponent 也需要,所以繼續傳遞下去
function DComponent({ name }) {
  return (
    <>
      <h1>{name}</h1>
      <EComponent name={name} />
    </>
  );
}

// 沒有使用到 name 屬性,單純傳遞下去
function EComponent({ name }) {
  return <FComponent name={name} />
}

// 有使用到 name 屬性
function FComponent({ name }) {
  return <h1>{name}</h1>;
}

Context API

Context API 是 React 提供的一種解決方案,允許我們在整個應用程式中共享資料或狀態,而不必手動傳遞它們到每個元件,Context API 包含以下概念:

  1. Provider:Provider 元件允許我們定義一個 context,並提供資料以供子元件使用,通常,Provider 會放在應用程式的頂層。
  2. Value:我們希望共享的資料,通常是狀態或函式。
  3. Consumers:Consumers 是訂閱 context 的元件,它們能夠從 context 中讀取資料。每當 context 的值發生變化時,所有的 Consumers 也會自動重新渲染。

開始使用 Context API

首先,我們使用 createContext 函式來創建一個自定義的 context(NameContext),這個 context 將用於我們希望在多個元件之間共享的資料。

import { createContext } from "react";

const NameContext = createContext();

接下來,我們使用 NameContext.Provider 來包住我們希望共享資料的元件,value 屬性是想要共享的資料狀態,通常是包含狀態和函式的一個物件。

function AComponent() {
  const [name, setName] = useState("John");

  return (
    <NameContext.Provider
      value={{
        name,
        setName
      }}
    >
      <BComponent />
    </NameContext.Provider>
  );
}

最後,在需要使用共享資料的元件中,透過 useContext 這一個 Hook 來讀取 context 中的資料,並且解構出我們需要的值,這樣子我們就不需要把 namesetName 透過 props 一路從 AComponent 傳遞到 FComponent 了。

function FComponent() {
  // useContext(NameContext) 回傳一個包含 name 和 setName 的物件,因此可以使用物件解構
  const { name, setName } = useContext(NameContext);
  
  return (
    <>
      <h1>{name}</h1>
      <button type="button" onClick={() => setName("Mark")}>
        Change Name
      </button>
    </>
  );
}

結語

當我們遇到在多層級的元件之間傳遞 props 時出現的 Prop Drilling 問題,Context API 是 React 提供的一種解決方案,透過建立共享的 context 和 provider,我們能夠更輕鬆地讀取和更新共享資料。


上一篇
Day 25 - 在 URL 中儲存資料:動態路由
下一篇
Day 27 - 記憶元件:memo
系列文
React 個人讀書會30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言